Spring security 会话管理
会话管理的基本概念可以理解为,管理会话的限制,就比如在大型的站点之中,基本上都是不允许多个帐号同时登录的,就比如腾讯QQ,假如PC1已经登入QQ,PC2再次登入QQ则会出现PC1QQ已经被踢下线的情况。而在网络设备中,只要该设备被登录,就不会允许再次登录的这种功能效果,Spring security为我们提供了完善的会话管理功能,和安全防御手段如:会话固定攻击,会话超时检测以及会话并发控制等。
什么是会话?
会话(session)即无状态的HTTP实现用户状态可维持的一种解决方案,在通常的情况每个请求之间都没有相互的关联性,也就是说用户访问的时候没有一个身份记录,也就是说谁都访问了,但是我不知道也查不到。session的出现解决了这个问题,服务器通过与用户达成一个约定,每个请求之间都携带着一个id类的信息。
在用户首次访问的时候,系统会为该程序生成一个sessionId,并因此添加至cookie之中,当用户的会话期限内,每个请求都会自动携带该cookie,因此系统会轻易的判断这个识别是来此那个一个用户的请求。
Spring security 的会话固定攻击防御
在spring security之中,会话固定个攻击的防御手段也可通过用户登录之后重新生成新的session,在继承WebSecurityConfigurationAdapter的时候,Spring security则已经启用了这种配置。
sessionManagement
sessionManagement是一个会话管理的配置器,其中防御会话固定攻击的策略分为四种分别为:
- 1.nune:不做任何改动,登入之后沿用旧的session
- 2.newSession:登录后创建一个新的session
- 3.migrateSession:登入之后创建一个新的session,并将旧的session中的数据复制过来
- 4.changeSessionId:不创建新的会话,而是使用由Servlet容器提供的会话固定保护。
WebSecurityConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService;
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private UserDetailsService userDetailsService;
@Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests() .anyRequest().authenticated() .and().formLogin() .and() .rememberMe() .userDetailsService(userDetailsService) .and() .sessionManagement() .sessionFixation().none(); }
}
|
实际上在Spring security之中,即使没有配置,也不需要太过担心会话固定攻击,因为Security之中的HTTP防火墙或控制器会帮助我们拦截一定的不合法URL请求,就比如我压根没配置index,你访问了只能是Error Page的错误页。
Spring security 会话管理配置
在Spring security之中,我们可通过invalidSessionUrl来指定会话的失效时重定向的URL(默认重定向登录页面)。当然也可通过maximumSession来指定用户最大的并发数量(-1表示无限制),这里我们主要列举几个简单的例子来实现。
失效处理与失效时间
通过sessionManagement().invalidSessionUrl();来设置会话失效后重定向的页面,这里我们在application.propertoes中分别设置session与cokie的生命周期:
application.properties
1 2 3 4 5 6 7 8
| spring.security.user.name=kun spring.security.user.password=123
# 根据提示默认时间是30min(单位为秒),这里我们设置60m(一分钟),通过查看 TomcatServletWebServerFactory # 我们可以得知session的默认时间是1分钟 server.servlet.session.timeout=60 # 这里是cookie的生命周期,单位为秒,-1是无限制 server.servlet.session.cookie.max-age=-1
|
WebSecurityConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService;
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private UserDetailsService userDetailsService;
@Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests() .anyRequest().authenticated() .and().formLogin() .and() .rememberMe() .userDetailsService(userDetailsService) .and() .sessionManagement() .invalidSessionUrl("/myLogin.html"); }
}
|
由于我们并没有自定义登录页面所以```/myLogin.html `` `文件坐在resource/static目录下为空,所以在session会话失效的时候自然就跳转到了spring security为我们提供的默认登录页面之中,读者可根据需求自行进行修改与调整。
session 最大会话数量
通过.maximumSessions我们可以管理session中同一用户的最大会话数量,如果.maximumSessions设置为”-1“则表示无限制,除此之外的其他数字都将会被限制。而本次我们通过WebSecurityConfig.java中的.invalidSessionUrl来指定其同一用户登入后如session没过期的情况下跳转至/myLogin.html页面,而.maxSessionsPreventsLogin所表示的则是,用户session会话达到.maximumSessions的限制后,新的请求session将会被拒绝登录。
WebSecurityConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.example.demo.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService;
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private UserDetailsService userDetailsService;
@Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests() .anyRequest().authenticated() .and().formLogin() .and() .rememberMe() .userDetailsService(userDetailsService) .and() .sessionManagement() .invalidSessionUrl("/myLogin.html") .maximumSessions(1).maxSessionsPreventsLogin(true); }
}
|
⬅️ Go back